#pragma once

#include <memory>
#include "rtda/frame.h"
#include "native/registry.h"

namespace jvm {
    namespace lang {

        class ClassNative {
        private:
            static const std::string JL_CLASS;

        public:
            static void init() {
                native::Registry::registerMethod(JL_CLASS, "getPrimitiveClass",
                    "(Ljava/lang/String;)Ljava/lang/Class;", &getPrimitiveClass);
                native::Registry::registerMethod(JL_CLASS, "getName0",
                    "()Ljava/lang/String;", &getName0);
                native::Registry::registerMethod(JL_CLASS, "desiredAssertionStatus0",
                    "(Ljava/lang/Class;)Z", &desiredAssertionStatus0);

                native::Registry::registerMethod(JL_CLASS, "isInterface", "()Z", &isInterface);
                native::Registry::registerMethod(JL_CLASS, "isPrimitive", "()Z", &isPrimitive);


                //native::Registry::registerMethod(JL_CLASS, "getDeclaredFields0", "(Z)[Ljava/lang/reflect/Field;", getDeclaredFields0);
                //native::Registry::registerMethod(JL_CLASS, "forName0", "(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;", forName0);
                //native::Registry::registerMethod(JL_CLASS, "getDeclaredConstructors0", "(Z)[Ljava/lang/reflect/Constructor;", getDeclaredConstructors0);
                //native::Registry::registerMethod(JL_CLASS, "getModifiers", "()I", getModifiers);

                native::Registry::registerMethod(JL_CLASS, "getSuperclass", "()Ljava/lang/Class;", &getSuperclass);

                //native::Registry::registerMethod(JL_CLASS, "getInterfaces0", "()[Ljava/lang/Class;", getInterfaces0);
                //native::Registry::registerMethod(JL_CLASS, "isArray", "()Z", isArray);
                //native::Registry::registerMethod(JL_CLASS, "getDeclaredMethods0", "(Z)[Ljava/lang/reflect/Method;", getDeclaredMethods0);
                //native::Registry::registerMethod(JL_CLASS, "getComponentType", "()Ljava/lang/Class;", getComponentType);
                //native::Registry::registerMethod(JL_CLASS, "isAssignableFrom", "(Ljava/lang/Class;)Z", isAssignableFrom);
            }

            static void getPrimitiveClass(std::shared_ptr<rtda::Frame> frame);
            static void getName0(std::shared_ptr<rtda::Frame> frame);
            static void desiredAssertionStatus0(std::shared_ptr<rtda::Frame> frame);
            static void isInterface(std::shared_ptr<rtda::Frame> frame);
            static void isPrimitive(std::shared_ptr<rtda::Frame> frame);

            //static void getDeclaredFields0(std::shared_ptr<rtda::Frame> frame);
            //static void forName0(std::shared_ptr<rtda::Frame> frame);
            //static void getDeclaredConstructors0(std::shared_ptr<rtda::Frame> frame);
            //static void getModifiers(std::shared_ptr<rtda::Frame> frame);

            static void getSuperclass(std::shared_ptr<rtda::Frame> frame);

            //static void getInterfaces0(std::shared_ptr<rtda::Frame> frame);
            //static void isArray(std::shared_ptr<rtda::Frame> frame);
            //static void getDeclaredMethods0(std::shared_ptr<rtda::Frame> frame);
            //static void getComponentType(std::shared_ptr<rtda::Frame> frame);
            //static void isAssignableFrom(std::shared_ptr<rtda::Frame> frame);
        };

    } // namespace lang
} // namespace jvm